package org.boot.fast.core;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import org.boot.fast.dao.ExcelConfigDAO;
import org.boot.fast.pojo.ExcelConfigDO;
import org.boot.fast.util.ConverterUtil;
import org.boot.fast.util.ExcelExporterUtil;
import org.boot.fast.util.ExcelImportUtil;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.boot.fast.util.GenericConverter.convertToTypedList;

/**
 * Excel 处理器
 * @author: 最爱芫荽
 * @email: 15733440205@163.com
 */
public class FastExcelProcess {

    private final static ExcelConfigDAO excelConfigDAO;

    static {
        excelConfigDAO = SpringUtil.getBean(ExcelConfigDAO.class);
    }

    /**
     * 导出Excel，响应byte[]字节码数据
     * @param list 数据列表
     * @param key  导出配置键值
     * @return Excel字节码
     */
    public static byte[] exportExcel(List<?> list, String key) {
        ExcelConfigDO excelConfig = getExcelConfig(key);
        return ExcelExporterUtil.exportExcel(
                ConverterUtil.convertToMap(list),
                JSON.parseObject(excelConfig.getConfigJson(), LinkedHashMap.class)
                );
    }

    /**
     * 导出Excel，响应文件
     * @param list 数据列表
     * @param key  导出配置键值
     * @param response HttpServletResponse
     */
    public static byte[] exportExcel(List<?> list, String key, HttpServletResponse response) {
        ExcelConfigDO excelConfig = getExcelConfig(key);

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + excelConfig.getTableName() + ".xlsx");

        return ExcelExporterUtil.exportExcel(
                ConverterUtil.convertToMap(list),
                JSON.parseObject(excelConfig.getConfigJson(), LinkedHashMap.class)
                );
    }

    /**
     * 解析Excel，返回 Map 列表
     * @param file Excel文件
     * @param key  导入配置键值
     * @return     数据列表（Map格式）
     */
    public static List<Map<String, Object>> analysisExcel(MultipartFile file, String key) {
        ExcelConfigDO excelConfig = getExcelConfig(key);
        return ExcelImportUtil.analysisExcel(file, reverseMap(JSON.parseObject(excelConfig.getConfigJson())));
    }

    /**
     * 解析Excel，返回实体列表
     * @param file Excel文件
     * @param key  导入配置键值
     * @param clazz 实体类
     * @return     数据列表（实体格式）
     */
    public static <T> List<T> analysisExcel(MultipartFile file, String key, Class<T> clazz) {
        ExcelConfigDO excelConfig = getExcelConfig(key);
        List<Map<String, Object>> list = ExcelImportUtil.analysisExcel(file, reverseMap(JSON.parseObject(excelConfig.getConfigJson())));
        if(list.isEmpty()) return null;
//        String json = JSON.toJSONString(list);
        return convertToTypedList(list, clazz);
    }


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    /**
     * 获取Excel配置
     * @param key 配置键值
     * @return Excel配置
     */
    private static ExcelConfigDO getExcelConfig(String key){
        ExcelConfigDO excelConfig = excelConfigDAO.findByKey(key);
        if(excelConfig == null || excelConfig.getConfigJson() == null) throw new IllegalArgumentException("excel配置不存在!");
        return excelConfig;
    }

    /**
     * 反转Map键值对
     * @param map 原始Map
     * @return 反转后的Map
     */
    private static Map<String, Object> reverseMap(Map<String, Object> map){
        Map<String, Object> result = new HashMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            result.put(entry.getValue().toString(), entry.getKey());
        }
        return result;
    }
}
